﻿using System;
using System.Runtime.InteropServices;
using Unity;
using UnityEngine;
using UnityEngine.Networking;

public class Look : CharacterBehaviour
{
    public Vector3 direction;
    public bool disableNetwork;
    private static int kCmdCmdSetDirection = 0x38df8fdc;
    private Vector3 lastDir;
    public float speed = 100f;
    [SyncVar]
    private NetworkDirection syncDirection;

    static Look()
    {
        NetworkBehaviour.RegisterCommandDelegate(typeof(Look), kCmdCmdSetDirection, new NetworkBehaviour.CmdDelegate(Look.InvokeCmdCmdSetDirection));
        NetworkCRC.RegisterBehaviour("Look", 0);
    }

    public void CallCmdSetDirection(NetworkDirection value)
    {
        if (!NetworkClient.active)
        {
            Debug.LogError("Command function CmdSetDirection called on server.");
        }
        else if (base.isServer)
        {
            this.CmdSetDirection(value);
        }
        else
        {
            NetworkWriter writer = new NetworkWriter();
            writer.Write((short) 0);
            writer.Write((short) ((ushort) 5));
            writer.WritePackedUInt32((uint) kCmdCmdSetDirection);
            writer.Write(base.GetComponent<NetworkIdentity>().netId);
            GeneratedNetworkCode._WriteNetworkDirection_None(writer, value);
            base.SendCommandInternal(writer, 0, "CmdSetDirection");
        }
    }

    [Command]
    private void CmdSetDirection(NetworkDirection value)
    {
        this.NetworksyncDirection = value;
    }

    protected static void InvokeCmdCmdSetDirection(NetworkBehaviour obj, NetworkReader reader)
    {
        if (!NetworkServer.active)
        {
            Debug.LogError("Command CmdSetDirection called on client.");
        }
        else
        {
            ((Look) obj).CmdSetDirection(GeneratedNetworkCode._ReadNetworkDirection_None(reader));
        }
    }

    public void LookAt(Vector3 direction)
    {
        this.direction = direction;
        this.NetworksyncDirection = direction;
        base.transform.rotation = Quaternion.LookRotation(direction);
    }

    public override void OnDeserialize(NetworkReader reader, bool initialState)
    {
        base.OnDeserialize(reader, initialState);
        if (initialState)
        {
            this.syncDirection = GeneratedNetworkCode._ReadNetworkDirection_None(reader);
        }
        else if ((reader.ReadPackedUInt32() & 1) != 0)
        {
            this.syncDirection = GeneratedNetworkCode._ReadNetworkDirection_None(reader);
        }
    }

    public override bool OnSerialize(NetworkWriter writer, bool forceAll)
    {
        bool flag2 = base.OnSerialize(writer, forceAll);
        if (forceAll)
        {
            GeneratedNetworkCode._WriteNetworkDirection_None(writer, this.syncDirection);
            return true;
        }
        bool flag = false;
        if ((base.syncVarDirtyBits & 1) != 0)
        {
            if (!flag)
            {
                writer.WritePackedUInt32(base.syncVarDirtyBits);
                flag = true;
            }
            GeneratedNetworkCode._WriteNetworkDirection_None(writer, this.syncDirection);
        }
        if (!flag)
        {
            writer.WritePackedUInt32(base.syncVarDirtyBits);
        }
        return (flag | flag2);
    }

    private void UNetVersion()
    {
    }

    protected virtual void Update()
    {
        this.direction.y = 0f;
        if (this.direction != Vector3.zero)
        {
            base.transform.rotation = Quaternion.RotateTowards(base.transform.rotation, Quaternion.LookRotation(this.direction), this.speed);
        }
        this.UpdateNetwork();
    }

    private void UpdateNetwork()
    {
        if (!this.disableNetwork && NetworkUtility.isNetworkActive)
        {
            if (base.hasAuthority)
            {
                if (Vector3.Angle(this.lastDir.normalized, this.direction.normalized) > 30f)
                {
                    this.CallCmdSetDirection(this.direction);
                    this.lastDir = this.direction;
                }
            }
            else if (this.syncDirection != Vector3.zero)
            {
                base.transform.rotation = Quaternion.Slerp(base.transform.rotation, Quaternion.LookRotation((Vector3) this.syncDirection), Time.deltaTime * 8f);
            }
        }
    }

    public NetworkDirection NetworksyncDirection
    {
        get
        {
            return this.syncDirection;
        }
        [param: In]
        set
        {
            base.SetSyncVar<NetworkDirection>(value, ref this.syncDirection, 1);
        }
    }
}

